package com.fxcalibre.fxml.control;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Set;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;

import com.fxcalibre.db.beans.Crew;
import com.fxcalibre.db.beans.CrewPk;
import com.fxcalibre.db.beans.MediaItem;
import com.fxcalibre.db.beans.Person;
import com.fxcalibre.fxml.control.events.DataChangedEvent;
import com.fxcalibre.fxml.control.listCells.PersonCell;
import com.fxcalibre.fxml.view.FXMLViewLoader;
import com.fxcalibre.hibernate.HibernateUtils;
import com.fxcalibre.syncservices.imdb.ImdbTitleSearch;
import com.fxcalibre.syncservices.imdb.parser.TitleResult;
import com.fxcalibre.utils.Constants;
import com.fxcalibre.utils.HTTPUtils;
import com.fxcalibre.utils.StringUtils;

public class MediaDetail extends VBox
{
	Stage primaryStage;
	Stage dialogStage;

	@FXML
	TextField id;
	@FXML
	ComboBox<String> type;
	@FXML
	TextField title;
	@FXML
	TextField year;
	@FXML
	TextField file;
	@FXML
	TextField imdbId;
	@FXML
	TextField season;
	@FXML
	TextField episode;
	@FXML
	TextField parentId;

	@FXML
	ListView<Crew> crewView;
	ObservableList<Crew> crew = FXCollections.observableArrayList();
	MediaItem mediaItem;
	MediaItem parent;

	public MediaDetail()
	{
		FXMLViewLoader.load(this, "MediaDetail.fxml");
		crewView.setItems(crew);
		crewView.setCellFactory(new Callback<ListView<Crew>, ListCell<Crew>>()
		{
			@Override
			public ListCell<Crew> call(ListView<Crew> list)
			{
				return new PersonCell();
			}
		});
		type.getItems().addAll(Constants.mediaTypes);
	}

	private void repaint()
	{
		if (mediaItem != null && mediaItem.getItemId() > 0)
		{
			id.setText(String.valueOf(mediaItem.getItemId()));
			type.getSelectionModel().select(mediaItem.getType());
			title.setText(mediaItem.getName());
			year.setText(mediaItem.getYear());
			file.setText(mediaItem.getFile());

			System.out.println("mediaItem.getImdbId: " + mediaItem.getImdbId());
			imdbId.setText(mediaItem.getImdbId());

			if (mediaItem.getSeason() != null)
			{
				season.setText(String.valueOf(mediaItem.getSeason()));
			}

			if (mediaItem.getEpisode() != null)
			{
				episode.setText(String.valueOf(mediaItem.getEpisode()));
			}

			if (mediaItem.getParent() != null)
			{
				parentId.setText(mediaItem.getParent().getName());
			}

			parent = mediaItem.getParent();
			crew.addAll(mediaItem.getCrew());
		} else
		{

			id.setText("");
			title.setText("");
			year.setText("");
			file.setText("");
			imdbId.setText("");
			season.setText("");
			episode.setText("");
			parentId.setText("");
			crew.clear();
		}
	}

	public void setMediaItem(MediaItem selectedMediaItem)
	{
		if (selectedMediaItem != null && selectedMediaItem.getItemId() > 0)
		{
			mediaItem = (MediaItem) HibernateUtils.buscarPorId(MediaItem.class, selectedMediaItem.getItemId(), false);
		} else
		{
			this.mediaItem = selectedMediaItem;
		}
		repaint();
	}

	@FXML
	public void selectFile(ActionEvent event)
	{
		FileChooser fileChooser = new FileChooser();

		// Set extension filter
		// TODO Construir un extension filter
		FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("AVI files (*.avi)", "*.avi", "*.mp4", "*.mkv");
		fileChooser.getExtensionFilters().add(extFilter);

		// Show open file dialog
		File selectedFile = fileChooser.showOpenDialog(null);

		file.setText(selectedFile.getPath());
	}

	@FXML
	protected void saveMedia(ActionEvent event)
	{
		System.out.println("Save: " + title);
		mediaItem.setType(type.getSelectionModel().getSelectedItem());

		mediaItem.setName(title.getText());
		mediaItem.setYear(year.getText());
		mediaItem.setFile(file.getText());

		mediaItem.setImdbId(imdbId.getText());
		mediaItem.setSeason(StringUtils.isNotEmpty(season.getText()) ? Integer.parseInt(season.getText()) : null);
		mediaItem.setEpisode(StringUtils.isNotEmpty(episode.getText()) ? Integer.parseInt(episode.getText()) : null);

		Set<Crew> crewSet = mediaItem.getCrew();
		crewSet.clear();
		crewSet.addAll(crewView.getItems());

		mediaItem.setCrew(crewSet);

		mediaItem.setParent(parent);

		HibernateUtils.grabar(mediaItem);
		fireEvent(new DataChangedEvent());

		if (dialogStage != null)
		{
			dialogStage.close();
		}
	}

	@FXML
	protected void deleteMedia(ActionEvent event)
	{
		HibernateUtils.borrar(mediaItem);
		fireEvent(new DataChangedEvent());
	}

	@FXML
	protected void addPersonToMedia(ActionEvent event)
	{
		SelectPerson selectPerson = new SelectPerson();
		selectPerson.showInStage();
		Person person = selectPerson.getSelectedPerson();
		if (person != null)
		{
			Crew crewItem = new Crew(new CrewPk(mediaItem, person, selectPerson.getSelectedRole()));
			crew.add(crewItem);
		}
	}

	@FXML
	protected void selectParentSerie(ActionEvent event)
	{
		SelectSerie selectSerie = new SelectSerie();
		selectSerie.showInStage();
		if (selectSerie.getSelectedSerie() != null)
		{
			parent = selectSerie.getSelectedSerie();
			parentId.setText(parent.getName());
			System.out.println("Selected parent:" + parent);
		}
	}

	@FXML
	protected void deleteParentSerie(ActionEvent event)
	{
		parent = null;
		parentId.setText("");
	}

	@FXML
	protected void removePersonFromMedia(ActionEvent event)
	{
		Crew crewItem = crewView.getSelectionModel().getSelectedItem();
		crew.remove(crewItem);
		// HibernateUtils.borrar(crewItem);
	}

	@FXML
	protected void syncByImdbId(ActionEvent event)
	{
		if (StringUtils.isNotEmpty(imdbId.getText()))
		{
			HashMap<String, String> result = ImdbTitleSearch.findById(imdbId.getText());
			System.out.println("Result: " + result);
			if (result.containsKey("name"))
			{
				title.setText(result.get("name"));
			}
		}
	}

	@FXML
	protected void searchImdb(ActionEvent event)
	{
		if (StringUtils.isNotEmpty(title.getText()))
		{

			System.out.println("abrimos buscador de pelis");
			ImdbSearchTitleResult imdbSearchTitleResult = new ImdbSearchTitleResult();
			imdbSearchTitleResult.setTitle(title.getText());
			imdbSearchTitleResult.showInStage();
			if (imdbSearchTitleResult.getSelectedTitleResult() != null)
			{
				TitleResult titleResult = imdbSearchTitleResult.getSelectedTitleResult();
				System.out.println("Seleccionado: " + titleResult.getId());

				mediaItem.setName(titleResult.getName());
				mediaItem.setImdbId(titleResult.getId());
				// image.setImage(new Image(nameResult.getImgUrl()));
				try
				{
					HTTPUtils.downloadImage(titleResult.getImgUrl(), mediaItem.getImgName());
				} catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				repaint();

			}
		}

	}

	@FXML
	protected void openFolder(ActionEvent event)
	{

		Desktop desktop = Desktop.getDesktop();
		try
		{
			desktop.open(new File(mediaItem.getFile()).getParentFile());
		} catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void setPrimaryStage(Stage primaryStage)
	{
		this.primaryStage = primaryStage;
	}

	public void showInStage()
	{
		dialogStage = new Stage();
		dialogStage.setTitle("Edit Media");
		dialogStage.initModality(Modality.APPLICATION_MODAL);
		dialogStage.initOwner(primaryStage);
		Scene scene = new Scene(this);
		scene.getStylesheets().add("com/fxcalibre/css/litefxcalibre.css");

		dialogStage.setScene(scene);
		dialogStage.showAndWait();
	}

}
